#include "SpringScrollViewComponentInstance.h"
#include "Types.h"
#include <folly/dynamic.h>
#include "RNOH/arkui/ArkUINode.h"
#include "RNOH/arkui/ScrollNode.h"
#include "RNOHCorePackage/ComponentInstances/ScrollViewComponentInstance.h"
#include <arkui/native_interface.h>
#include <arkui/native_node.h>
#include "RNOH/arkui/NativeNodeApi.h"

namespace rnoh {
    SpringScrollViewComponentInstance::SpringScrollViewComponentInstance(Context context)
        : CppComponentInstance(std::move(context)) {

        m_springStackNode.insertChild(m_headerStackNode, 0);
        m_springStackNode.insertChild(m_scrollViewStackNode, 1);
        m_springStackNode.insertChild(m_footerStackNode, 2);
        m_springStackNode.setSpringScrollViewNodeDelegate(this);
        ArkUI_NumberValue clipValue[] = {{.u32 = 1}};
        ArkUI_AttributeItem clipItem = {clipValue, sizeof(clipValue) / sizeof(ArkUI_NumberValue)};
        NativeNodeApi::getInstance()->setAttribute(m_headerStackNode.getArkUINodeHandle(), NODE_CLIP, &clipItem);
    }

    void SpringScrollViewComponentInstance::onChildInserted(ComponentInstance::Shared const &childComponentInstance,
                                                            std::size_t index) {
        CppComponentInstance::onChildInserted(childComponentInstance, index);
        if (!isHeaderInserted) {
            m_headerStackNode.insertChild(childComponentInstance->getLocalRootArkUINode(), index);
            isHeaderInserted = true;
        } else if (!isFooterInserted) {
            m_footerStackNode.insertChild(childComponentInstance->getLocalRootArkUINode(), index);
            isFooterInserted = true;
        } else {
            m_scrollViewStackNode.insertChild(childComponentInstance->getLocalRootArkUINode(), index);
        }
        auto nodeValue = NativeNodeApi::getInstance()->getAttribute(m_springStackNode.getArkUINodeHandle(), NODE_WIDTH);
        initialContentOffset.x = nodeValue->value[nodeValue->size - 1].f32;
        m_headerStackNode.setSize(facebook::react::Size({initialContentOffset.x, 0}));
    }

    void SpringScrollViewComponentInstance::onChildRemoved(ComponentInstance::Shared const &childComponentInstance) {
        CppComponentInstance::onChildRemoved(childComponentInstance);
        m_headerStackNode.removeChild(childComponentInstance->getLocalRootArkUINode());
        m_scrollViewStackNode.removeChild(childComponentInstance->getLocalRootArkUINode());
        m_footerStackNode.removeChild(childComponentInstance->getLocalRootArkUINode());
    };

    SpringScrollViewNode &SpringScrollViewComponentInstance::getLocalRootArkUINode() { return m_springStackNode; }

    void SpringScrollViewComponentInstance::onPropsChanged(SharedConcreteProps const &props) {
        CppComponentInstance::onPropsChanged(props);
        if (props == nullptr) {
            return;
        }
        if (auto p = std::dynamic_pointer_cast<const facebook::react::RNCSpringScrollViewProps>(props)) {
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> refreshHeaderHeight: "
                         << p->refreshHeaderHeight;
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> decelerationRate: "
                         << p->decelerationRate;
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> loadingFooterHeight: "
                         << p->loadingFooterHeight;
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> bounces: " << p->bounces;
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> allLoaded: " << p->allLoaded;
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> inverted: " << p->inverted;
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> scrollEnabled: " << p->scrollEnabled;
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> pagingEnabled: " << p->pagingEnabled;
            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> directionalLockEnabled: "
                         << p->directionalLockEnabled;

            LOG(WARNING) << "[clx] <SpringScrollViewComponentInstance::setProps> initialContentOffset: "
                         << p->initialContentOffset.x + ':' + p->initialContentOffset.y;


            this->getLocalRootArkUINode().setInitialContentOffset(p->initialContentOffset.x, p->initialContentOffset.y);
            this->getLocalRootArkUINode().setRefreshHeaderHeight(p->refreshHeaderHeight);
            this->getLocalRootArkUINode().setLoadingFooterHeight(p->loadingFooterHeight);
            this->getLocalRootArkUINode().setDecelerationRate(p->decelerationRate);
            this->getLocalRootArkUINode().setBounces(p->bounces);
            this->getLocalRootArkUINode().setAllLoaded(p->allLoaded);
            this->getLocalRootArkUINode().setInverted(p->inverted);
            this->getLocalRootArkUINode().setScrollEnabled(p->scrollEnabled);
            this->getLocalRootArkUINode().setPagingEnabled(p->pagingEnabled);
            this->getLocalRootArkUINode().setPageSize(p->pageSize.width, p->pageSize.height);
            this->getLocalRootArkUINode().setDirectionalLockEnabled(p->directionalLockEnabled);
        }
    }

    void SpringScrollViewComponentInstance::onRefresh() { m_eventEmitter->onRefresh({}); };
    void SpringScrollViewComponentInstance::onLoading() { m_eventEmitter->onLoading({}); };
    void SpringScrollViewComponentInstance::onTouchBegin() { m_eventEmitter->onTouchBegin({}); };
    void SpringScrollViewComponentInstance::onTouchEnd() { m_eventEmitter->onTouchEnd({}); };
    void SpringScrollViewComponentInstance::onMomentumScrollBegin() { m_eventEmitter->onMomentumScrollBegin({}); };
    void SpringScrollViewComponentInstance::onMomentumScrollEnd() { m_eventEmitter->onMomentumScrollEnd({}); };
    void SpringScrollViewComponentInstance::onScroll() { m_eventEmitter->onScroll({}); };
    void SpringScrollViewComponentInstance::onSizeChange() { m_eventEmitter->onSizeChange({}); };
    void SpringScrollViewComponentInstance::onContentSizeChange() { m_eventEmitter->onContentSizeChange({}); };

    void SpringScrollViewComponentInstance::getNapiProps(facebook::react::Props::Shared props) {
        auto p = std::dynamic_pointer_cast<const facebook::react::RNCSpringScrollViewProps>(props);
        refreshHeaderHeight = p->refreshHeaderHeight;
        decelerationRate = p->decelerationRate;
        loadingFooterHeight = p->loadingFooterHeight;
        bounces = p->bounces;
        inverted = p->inverted;
        allLoaded = p->allLoaded;
        scrollEnabled = p->scrollEnabled;
        pagingEnabled = p->pagingEnabled;
        initialContentOffset.x = p->initialContentOffset.x;
        initialContentOffset.y = p->initialContentOffset.y;
        pageSize.width = p->pageSize.width;
        pageSize.height = p->pageSize.height;
    }
} // namespace rnoh